

#include "CornerGrid.h"
#include "Dream3DRender.h"
#include <glm/glm.hpp>
#include <iostream>
#include <mutex>

//计算四变形的编号
size_t hashCombine(size_t a, size_t b, size_t c, size_t d)
{
  size_t hashA = std::hash<size_t>{}(a);
  size_t hashB = std::hash<size_t>{}(b);
  size_t hashC = std::hash<size_t>{}(c);
  size_t hashD = std::hash<size_t>{}(d);

  // 混合哈希值
  size_t combinedHash = hashA;
  combinedHash ^= (hashB << 1);  // 左移1位并异或
  combinedHash ^= (hashC << 2);  // 左移2位并异或
  combinedHash ^= (hashD << 3);  // 左移3位并异或

  return combinedHash;
}

CornerGrid::CornerGrid() {}

CornerGrid::~CornerGrid() {}

//数据初始化
void CornerGrid::InitData()
{
  ofstream log;
  log.open("InitData.txt");

  std::string msg;
  msg = "扫描数据文件";
  log << msg << std::endl;

  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 5);
  }
  clock_t start_time = std::clock();
  Rpt.Scan(mFilePath);  // Scan files first
  clock_t end_time = std::clock();
  log << "扫描数据时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;
  msg = "扫描数据文件完成";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 10);
  }
  // std::cout << "Overall grid size=" << Rpt.GrossSize() << ", active grid=" << Rpt.NetSize() << ", number of time step=" << Rpt.NStep() << "\n" <<
  // std::endl; std::cout << "Grid static properties: " << std::endl;

  stat_props = Rpt.stat_props;

  for (const Name_Loc& info : stat_props)
  {
    // std::cout << "    Name: " << info.name << ", length: " << info.length << ", unit: " << info.unit << ", is at cell center: " << info.on_grid <<
    // std::endl;
    if (info.name == "GRID_VTX")
    {
      mPointCount = info.length;
    }
  }
  if (mPointCount == 0)
  {
    msg = "没有顶点";
    log << msg << std::endl;
    if (mProgressFunction)
    {
      mProgressFunction(msg, 0, 100);
    }
    log.close();
    return;
  }
  dym_props = Rpt.dym_props;
  // std::cout << "Grid dynamic properties: " << std::endl;
  // for (const std::vector<Name_Loc> dynamic_infos : Rpt.dym_props)
  //{
  //   if (!dynamic_infos.empty())
  //   {
  //     std::cout << "  Time: " << dynamic_infos[0].time << ", time type: " << dynamic_infos[0].time_type << std::endl;
  //   }
  //   for (const Name_Loc& info : dynamic_infos)
  //   {
  //     std::cout << "    Name: " << info.name << ", length: " << info.length << ", unit: " << info.unit << ", is at cell center: " << info.on_grid
  //     << std::endl;
  //   }
  // }

  Rpt.GetAxisOffset(mOffset.x, mOffset.y, mOffset.z);
  // std::cout << "Axis_offset=(" << x0 << ", " << y0 << ", " << d0 << ")" << std::endl;
  log << "获取节点..." << std::endl;
  msg = "获取节点...";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 20);
  }
  // PropArray gridinfo;
  // bool findgridinfo = Rpt.GetStaticData(stat_props[0].name, gridinfo);
  // UGINT64 NumBaseGrid       = Rpt.NumBaseGrid();
  // UGINT64 NumActBaseGrid    = Rpt.NumActBaseGrid();
  // UGINT64 NumFLvActBaseGrid = Rpt.NumFLvActBaseGrid();
  // UGINT64 NumMtxActBaseGrid = Rpt.NumMtxActBaseGrid();
  // UGINT64 NumFineGrid       = Rpt.NumFineGrid();
  // UGINT64 NumActFineGrid    = Rpt.NumActFineGrid();
  // UGINT64 NumFLvActFineGrid = Rpt.NumFLvActFineGrid();
  // UGINT64 NumMtxActFineGrid = Rpt.NumMtxActFineGrid();
  ////Embedded fracture
  // UGINT64 NumEmdfFace    = Rpt.NumEmdfFace();
  // UGINT64 NumActEmdfFace = Rpt.NumActEmdfFace();
  // Rpt.ReMap(gridinfo.fdata, nullptr, nullptr, &(Rpt.Gross2Net[0]), &(Rpt.Net2Gross[0]));

  start_time          = std::clock();
  bool find_NODE_LIST = Rpt.GetStaticData("NODE_LIST", NODE_LIST_array);
  end_time            = std::clock();
  log << "获取节点时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;
  msg = "获取节点完成";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 30);
  }
  if (NODE_LIST_array.length < 8 || !find_NODE_LIST)
  {
    msg = "获取节点失败";
    log << msg << std::endl;
    log.close();
    return;
  }
  mGridCount   = NODE_LIST_array.length / 8;
  mpActiveGrid = new bool[mGridCount];
  memset(mpActiveGrid, 1, mGridCount * sizeof(bool));

  mVox.a = this->SGridNI();
  mVox.b = this->SGridNJ();
  mVox.c = this->SGridNK();
  // int ix, iy, iz;
  // IDTOXYZ(40, mVox, ix,iy,iz);
  // 顶点引用计数
  mpPointRefCount = new short[mPointCount];
  memset(mpPointRefCount, 0, mPointCount * sizeof(short));

  start_time = std::clock();
  log << "顶点数：" << mPointCount << std::endl;
  log << "计算顶点引用次数" << std::endl;
  size_t pointID = 0;

  msg = "计算顶点拓扑关系";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 40);
  }

#pragma omp parallel for
  for (UGINT64 k = 0; k < NODE_LIST_array.length; ++k)
  {
    mpPointRefCount[(size_t)NODE_LIST_array.fdata[k] - 1] += 1;
  }
  // debug
  // memset(mpActiveGrid, 0, gridCeilCount * sizeof(bool));
  // mpActiveGrid[0] = 1;
  // FilterInner();

  end_time = std::clock();
  log << "计算顶点引用次数完完成，时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;

  msg = "计算顶点拓扑关系完成";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 50);
  }

  log << "获取顶点..." << std::endl;
  msg = "获取顶点...";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 75);
  }
  start_time         = std::clock();
  bool find_GRID_VTX = Rpt.GetStaticData("GRID_VTX", GRID_VTX_array);
  if (!find_GRID_VTX)
  {
    msg = "获取顶点失败";
    log << msg << std::endl;
    log.close();
    return;
    // std::cout << "Find GRID_VTX, length=" << GRID_VTX_array.length << ", number of vertex=" << GRID_VTX_array.length / 3 << std::endl;
  }
  end_time = std::clock();
  log << "获取顶点时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;
  msg = "获取顶点完成";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 80);
  }
  log.close();
  mNeedRebuild = true;
}
//获取IJK
void CornerGrid::GetIJKSize(vsg::ivec3& minIJK, vsg::ivec3& maxIJK)
{
  minIJK.x = 0;
  minIJK.y = 0;
  minIJK.z = 0;
  maxIJK.x = this->SGridNI();
  maxIJK.y = this->SGridNJ();
  maxIJK.z = this->SGridNK();
}

bool CornerGrid::Init(vsg::vec3& minVec, vsg::vec3& maxVec, std::vector<Vertex>& outVertex, std::vector<uint32_t>& indices)
{

  return true;
}

bool CornerGrid::Init(RenderData* pData)
{
  InitData();
  VEC_PropArray vec_atts;
  PropArray POIL1_array;

  int timeStep = dym_props.size();

  if (GetValue(1, "POIL", POIL1_array))
  {
    vec_atts.push_back(&POIL1_array);
  }
  PropArray POIL2_array;
  if (GetValue(2, "POIL", POIL2_array))
  {
    vec_atts.push_back(&POIL1_array);
  }
  PropArray POIL3_array;
  if (GetValue(3, "POIL", POIL3_array))
  {
    vec_atts.push_back(&POIL3_array);
  }
  PropArray POIL4_array;
  if (GetValue(4, "POIL", POIL4_array))
  {
    vec_atts.push_back(&POIL4_array);
  }

  BuildGrid();
  return false;
}

void CornerGrid::FilterInner()
{
  // 过滤 不激活的
  std::string msg;
  msg = "过滤中...";
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 5);
  }
  memset(mpPointRefCount, 0, mPointCount * sizeof(short));
  size_t pointID = 0;
  size_t id[8];
//#pragma omp parallel for
  for (size_t k = 0; k < mGridCount; ++k)
  {
    if (!mpActiveGrid[k])
    {
      continue;
    }
    id[0] = (size_t)NODE_LIST_array.fdata[8 * k] - 1;
    id[6] = (size_t)NODE_LIST_array.fdata[8 * k + 6] - 1;
    id[2] = (size_t)NODE_LIST_array.fdata[8 * k + 2] - 1;
    id[4] = (size_t)NODE_LIST_array.fdata[8 * k + 4] - 1;
    id[1] = (size_t)NODE_LIST_array.fdata[8 * k + 1] - 1;
    id[7] = (size_t)NODE_LIST_array.fdata[8 * k + 7] - 1;
    id[3] = (size_t)NODE_LIST_array.fdata[8 * k + 3] - 1;
    id[5] = (size_t)NODE_LIST_array.fdata[8 * k + 5] - 1;
    for (int i = 0; i < 8; ++i)
    {
      mpPointRefCount[id[i]] += 1;
    }
  }
  mNeedRebuild = true;
  msg          = "过滤完成";
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 10);
  }
}
struct InnerData
{
  int tID = 0;
  float ValueSpan;
  float ValueMin;
  float ValueMax;
};
bool CornerGrid::BuildGrid()
{
  if (!mNeedRebuild)
  {
    return false;
  }
  if (mPointCount < 1 || mGridCount < 1)
  {
    return false;
  }
  ofstream log;
  log.open("BuildGrid.txt");
  RemoveCurrent();
  std::string msg;
  size_t id[8];
  // size_t gridCeilCount = NODE_LIST_array.length / 8;
  // mGridCount           = gridCeilCount;

  MAPQUADID::iterator itFindQuad;
  clock_t start_time = std::clock();
  log << "网格数：" << mGridCount << std::endl;
  log << "计算内，外部网格" << std::endl;

  msg = "计算网格拓扑";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 20);
  }
  clock_t end_time = std::clock();
  // log << "计算内外部网格完成,时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << std::endl;
  // log << "外部网格: " << mGrids.size() << std::endl;
  // log << "外部网格面: " << mQuads.size() << std::endl;
  unsigned int hardware_threads = std::thread::hardware_concurrency();
  start_time                    = std::clock();
  size_t oneThreadCount         = (mGridCount + hardware_threads) / hardware_threads;
  std::vector<CalcWorker*> allThreads;
  size_t lastStartID = 0;
  for (size_t k = 0; k < hardware_threads; ++k)
  {
    CalcWorker* pWork = new CalcWorker(mGrids, mpActiveGrid, mpPointRefCount, &GRID_VTX_array, &NODE_LIST_array, lastStartID,
                                       std::min(mGridCount, lastStartID + oneThreadCount));
    pWork->start();
    allThreads.push_back(pWork);
    if (lastStartID + oneThreadCount >= mGridCount)
    {
      break;
    }
    lastStartID = lastStartID + oneThreadCount;
  }
  for (size_t k = 0; k < allThreads.size(); ++k)
  {
    allThreads[k]->wait();
  }
  end_time = std::clock();
  log << "计算内外部网格,线程数: " << allThreads.size() << std::endl;
  log << "计算内外部网格,时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << std::endl;
  start_time = std::clock();
  MAPGRID::iterator itGrid;
  MAPGRID::iterator itGridBegin;
  MAPGRID::iterator itGridEnd;
  for (size_t k = 0; k < allThreads.size(); ++k)
  {
    itGridBegin = allThreads[k]->mGrids.begin();
    itGridEnd   = allThreads[k]->mGrids.end();
    for (itGrid = itGridBegin; itGrid != itGridEnd; ++itGrid)
    {
      GridQuad& grid = itGrid->second;
      for (int nq = 0; nq < 6; ++nq)
      {
        if (grid.quad[nq]->isshared)
        {
          continue;
        }
        itFindQuad = mQuads.find(grid.quad[nq]->id);
        if (itFindQuad == mQuads.end())
        {
          mQuads[grid.quad[nq]->id] = grid.quad[nq];
        }
        else
        {
          // 是公共面
          // 当前的
          grid.quad[nq]->isshared = true;
          // 已经存在的
          itFindQuad->second->isshared = true;
          // k;
          // itFindQuad->second->gridid;
          itFindQuad->second->shareids[0] = k;
          itFindQuad->second->shareids[1] = itFindQuad->second->gridid;
          grid.quad[nq]->shareids[0]      = k;
          grid.quad[nq]->shareids[1]      = itFindQuad->second->gridid;
        }
      }
    }
  }
  for (int k = 0; k < allThreads.size(); ++k)
  {
    delete allThreads[k];
  }
  allThreads.clear();

  end_time = std::clock();
  log << "计算内外部网格完成,时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << std::endl;
  msg = "计算顶点拓扑关系完成";
  log << msg << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 100);
  }
  log.close();
  mNeedRebuild = false;
  return true;
}

bool CornerGrid::GenGridRenderData(RenderData* pdata, std::vector<PropArray*>& atts)
{
  if (mPointCount < 1 || mGridCount < 1)
  {
    return false;
  }
  std::string msg;
  ofstream log;
  std::stringstream outStr;
  log.open("GenGridRenderData.txt");
  if (atts.size() < 1)
  {
    msg = "未设置属性 ";
    log << msg << std::endl;
    if (mProgressFunction)
    {
      mProgressFunction(msg, 0, 20);
    }
    return false;
  }
  if (pdata == nullptr)
  {
    msg = "传入参数错误 ";
    log << msg << std::endl;
    if (mProgressFunction)
    {
      mProgressFunction(msg, 0, 20);
    }
    return false;
  }
  mCurrentShowAtts = atts;
  pdata->box       = vsg::box(vsg::vec3(100000000, 100000000, 100000000), vsg::vec3(-100000000, -100000000, -100000000));

  size_t quadID  = 0;
  size_t gridID  = 0;
  float texcoord = 0;

  size_t indexa, indexb, indexc, indexd;
  float t1         = 0;
  float t2         = 0;
  float t3         = 0;
  float t4         = 0;
  size_t countQuad = 0;

  Vertex dotA;
  Vertex dotB;
  Vertex dotC;
  Vertex dotD;

  outStr << "预处理网格属性" << std::endl;
  log << outStr.str() << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(outStr.str(), 0, 50);
  }

  InnerData* AttValues = new InnerData[atts.size()];
  for (int it = 0; it < atts.size(); ++it)
  {
    if (atts[it]->length < mGridCount)
    {
      AttValues[it].ValueSpan = 0;
      continue;
    }
    AttValues[it].tID       = it;
    AttValues[it].ValueSpan = atts[it]->Max - atts[it]->Min;
    AttValues[it].ValueMin  = atts[it]->Min;
    AttValues[it].ValueMax  = atts[it]->Max;
  }

  MAPQUADID::iterator itQuad;
  MAPQUADID::iterator itQuadBegin = mQuads.begin();
  MAPQUADID::iterator itQuadEnd   = mQuads.end();
  size_t sizeQuad                 = mQuads.size();   
  pdata->SetPointSize(sizeQuad * 4);
  pdata->SetIndicesSize(sizeQuad * 6);

  vsg::ref_ptr<vsg::vec3Array>& vertices  = pdata->vertices;
  vsg::ref_ptr<vsg::vec3Array>& normals   = pdata->normals;
  vsg::ref_ptr<vsg::vec3Array>& ijks      = pdata->ijks;
  vsg::ref_ptr<vsg::vec4Array>& texcoords = pdata->texcoords;

  size_t pointIDV    = 0;
  size_t pointIDN    = 0;
  size_t pointIDIJK  = 0;
  size_t pointIDT    = 0;
  size_t indicesID   = 0;
  clock_t start_time = std::clock();
  clock_t end_time   = 0;
  bool bUseNet       = false;
  if (Rpt.Net2Gross.size() >= mGridCount)
  {
    bUseNet = true;
  }
  size_t realGridID = 0;
  for (itQuad = itQuadBegin; itQuad != itQuadEnd; ++itQuad)
  {
    if (itQuad->second->isshared)
    {
      continue;
    }
    realGridID = gridID = itQuad->second->gridid;

    dotA.pos[0] = GRID_VTX_array.fdata[3 * itQuad->second->a];
    dotA.pos[1] = GRID_VTX_array.fdata[3 * itQuad->second->a + 1];
    dotA.pos[2] = -GRID_VTX_array.fdata[3 * itQuad->second->a + 2];

    dotB.pos[0] = GRID_VTX_array.fdata[3 * itQuad->second->b];
    dotB.pos[1] = GRID_VTX_array.fdata[3 * itQuad->second->b + 1];
    dotB.pos[2] = -GRID_VTX_array.fdata[3 * itQuad->second->b + 2];

    dotC.pos[0] = GRID_VTX_array.fdata[3 * itQuad->second->c];
    dotC.pos[1] = GRID_VTX_array.fdata[3 * itQuad->second->c + 1];
    dotC.pos[2] = -GRID_VTX_array.fdata[3 * itQuad->second->c + 2];

    dotD.pos[0] = GRID_VTX_array.fdata[3 * itQuad->second->d];
    dotD.pos[1] = GRID_VTX_array.fdata[3 * itQuad->second->d + 1];
    dotD.pos[2] = -GRID_VTX_array.fdata[3 * itQuad->second->d + 2];

    pdata->box.min.x = std::min((double)pdata->box.min.x, (double)dotA.pos[0]);
    pdata->box.min.y = std::min((double)pdata->box.min.y, (double)dotA.pos[1]);
    pdata->box.min.z = std::min((double)pdata->box.min.z, (double)dotA.pos[2]);

    pdata->box.max.x = std::max((double)pdata->box.max.x, (double)dotA.pos[0]);
    pdata->box.max.y = std::max((double)pdata->box.max.y, (double)dotA.pos[1]);
    pdata->box.max.z = std::max((double)pdata->box.max.z, (double)dotA.pos[2]);
    glm::vec3 normal(0, 0, 1);
    {
      glm::vec3 dot1(dotA.pos[0], dotA.pos[1], dotA.pos[2]);
      glm::vec3 dot2(dotB.pos[0], dotB.pos[1], dotB.pos[2]);
      glm::vec3 dot3(dotC.pos[0], dotC.pos[1], dotC.pos[2]);
      normal = glm::cross((dot2 - dot1), dot3 - dot1);
      normal = glm::normalize(normal);
      if (normal.z < 0)
      {
        normal *= -1;
      }
    }
    dotA.normal[0] = normal.x;
    dotA.normal[1] = normal.y;
    dotA.normal[2] = normal.z;

    dotB.normal[0] = normal.x;
    dotB.normal[1] = normal.y;
    dotB.normal[2] = normal.z;

    dotC.normal[0] = normal.x;
    dotC.normal[1] = normal.y;
    dotC.normal[2] = normal.z;

    dotD.normal[0] = normal.x;
    dotD.normal[1] = normal.y;
    dotD.normal[2] = normal.z;
    if (bUseNet)
    {
      realGridID = Rpt.Net2Gross[gridID];
    }
    IDTOXYZ(realGridID, mVox, dotA.ijk.x, dotA.ijk.y, dotA.ijk.z);
    dotD.ijk = dotC.ijk = dotB.ijk = dotA.ijk;
    //if (dotA.ijk.x == 306 && dotA.ijk.y == 239 && dotA.ijk.z == 0)
    //{
    //  int kkk = 0;
    //}
    // long long outID;
    // if (gridID > 9894)
    //{
    //   Voxel vox = mVox;
    //   //vox.a = 1;
    //   //vox.b = 40 * 3;
    //   //vox.c = 120 * 19 * 3;
    //   IDTOXYZ(realGridID, vox, dotA.ijk.x, dotA.ijk.y, dotA.ijk.z);
    //   XYZTOID(vox, dotA.ijk.x, dotA.ijk.y, dotA.ijk.z, outID);
    // }
    for (int iT = 0; iT < 4 && iT < atts.size(); ++iT)
    {
      if (AttValues[iT].ValueSpan > 0 && atts[iT]->fdata)
      {
        texcoord = (atts[iT]->fdata[gridID] - atts[iT]->Min) / AttValues[iT].ValueSpan;
      }
      else
      {
        texcoord = 0;
      }
      dotA.uv[iT] = texcoord;
      dotB.uv[iT] = texcoord;
      dotC.uv[iT] = texcoord;
      dotD.uv[iT] = texcoord;
    }

    vertices->at(pointIDV++) = dotA.pos;
    vertices->at(pointIDV++) = dotB.pos;
    vertices->at(pointIDV++) = dotC.pos;
    vertices->at(pointIDV++) = dotD.pos;

    normals->at(pointIDN++) = dotA.normal;
    normals->at(pointIDN++) = dotB.normal;
    normals->at(pointIDN++) = dotC.normal;
    normals->at(pointIDN++) = dotD.normal;

    ijks->at(pointIDIJK++) = dotA.ijk;
    ijks->at(pointIDIJK++) = dotB.ijk;
    ijks->at(pointIDIJK++) = dotC.ijk;
    ijks->at(pointIDIJK++) = dotD.ijk;

    texcoords->at(pointIDT++) = dotA.uv;
    texcoords->at(pointIDT++) = dotB.uv;
    texcoords->at(pointIDT++) = dotC.uv;
    texcoords->at(pointIDT++) = dotD.uv;

    pdata->indices->at(indicesID++) = 4 * quadID;
    pdata->indices->at(indicesID++) = 4 * quadID + 1;
    pdata->indices->at(indicesID++) = 4 * quadID + 2;

    pdata->indices->at(indicesID++) = 4 * quadID;
    pdata->indices->at(indicesID++) = 4 * quadID + 2;
    pdata->indices->at(indicesID++) = 4 * quadID + 3;

    ++quadID;
  }

  delete[] AttValues;
  end_time = std::clock();
  outStr.clear();
  outStr << "生成显示数据时间: " << (double)(end_time - start_time) / CLOCKS_PER_SEC << "s" << std::endl;
  outStr << "顶点数:" << sizeQuad * 4 << std::endl;
  outStr << "索引:" << sizeQuad * 6 << std::endl;

  msg = "网格创建完成";
  log << outStr.str() << std::endl;
  if (mProgressFunction)
  {
    mProgressFunction(msg, 0, 100);
  }
  log.close();
  return true;
}

void CornerGrid::FilterAttDebug()
{
  bool bShow = true;
  for (long long k = 0; k < mGridCount; ++k)
  {
    this->mpActiveGrid[k] = bShow;
    bShow                 = !bShow;
  }
  FilterInner();
}

void CornerGrid::FilterShowIJKSection(int i0, int i1, int j0, int j1, int k0, int k1)
{
  int x, y, z;
  // 还原
  memset(mpActiveGrid, 1, mGridCount * sizeof(bool));
  bool bUseNet = false;
  if (Rpt.Net2Gross.size() >= mGridCount)
  {
    bUseNet = true;
  }
  size_t realGridID;
  for (UGINT64 k = 0; k < mGridCount; ++k)
  {
    if (bUseNet)
    {
      realGridID = Rpt.Net2Gross[k];
    }
    else
    {
      realGridID = k;
    }
    IDTOXYZ(realGridID, mVox, x, y, z);
    if (x < i0 || x > i1)
    {
      mpActiveGrid[k] = false;
      continue;
    }
    if (y < j0 || y > j1)
    {
      mpActiveGrid[k] = false;
      continue;
    }
    if (z < k0 || z > k1)
    {
      mpActiveGrid[k] = false;
      continue;
    }
  }
  FilterInner();
}

void CornerGrid::ShowIJKIDs(std::vector<int>& Iids, std::vector<int>& Jids, std::vector<int>& Kids)
{
  int x, y, z;
  // 还原
  memset(mpActiveGrid, 0, mGridCount * sizeof(bool));
  bool bUseNet = false;
  if (Rpt.Net2Gross.size() >= mGridCount)
  {
    bUseNet = true;
  }
  size_t realGridID;
  std::vector<int>::iterator itFind;
  for (UGINT64 k = 0; k < mGridCount; ++k)
  {
    if (bUseNet)
    {
      realGridID = Rpt.Net2Gross[k];
    }
    else
    {
      realGridID = k;
    }
    IDTOXYZ(realGridID, mVox, x, y, z);
    itFind = std::find(Iids.begin(), Iids.end(), x);
    if (itFind != Iids.end())
    {
      mpActiveGrid[k] = true;
      continue;
    }
    itFind = std::find(Jids.begin(), Jids.end(), y);
    if (itFind != Jids.end())
    {
      mpActiveGrid[k] = true;
      continue;
    }
    itFind = std::find(Kids.begin(), Kids.end(), z);
    if (itFind != Kids.end())
    {
      mpActiveGrid[k] = true;
    }
  }
  FilterInner();
}

void CornerGrid::ResetFilter()
{
  // 还原
  memset(mpActiveGrid, 1, mGridCount * sizeof(bool));
  FilterInner();
}

bool CornerGrid::GetValue(int index, std::string field, PropArray& outValues)
{
  if (index == 0)
  {
    return Rpt.GetStaticData(field, outValues);
  }
  return Rpt.GetDynamicData(index, field, outValues);
}

double CornerGrid::GetValue(int index, vsg::ivec3 ijk)
{
  if (mCurrentShowAtts.size() > index)
  {
    long long gridID = -1;
    XYZTOID(mVox, ijk.x, ijk.y, ijk.z, gridID);
    if (0 <= gridID && gridID < mCurrentShowAtts[index]->length)
    {
      return mCurrentShowAtts[index]->fdata[gridID];
    }
  }
  return InvalidValue;
}

bool CornerGrid::GetValueRange(int index, double& vMin, double& vMax)
{
  if (mCurrentShowAtts.size() > index)
  {
    vMin = mCurrentShowAtts[index]->Min;
    vMax = mCurrentShowAtts[index]->Max;
    return true;
  }
  return false;
}

void CornerGrid::RemoveCurrent()
{
  MAPGRID::iterator itGrid;
  MAPGRID::iterator itGridBegin = mGrids.begin();
  MAPGRID::iterator itGridEnd   = mGrids.end();
  for (itGrid = itGridBegin; itGrid != itGridEnd; ++itGrid)
  {
    for (int k = 0; k < 6; ++k)
    {
      delete itGrid->second.quad[k];
    }
  }
  mGrids.clear();
  mQuads.clear();
}

CalcWorker::CalcWorker(MAPGRID& grids, bool* active, short* pPointRefCount, PropArray* GRID_VTX_array, PropArray* NODE_LIST_array, size_t startID,
                       size_t endID)
  : mGrids(grids), mpActiveGrid(active), mpPointRefCount(pPointRefCount), pGRID_VTX_array(GRID_VTX_array), pNODE_LIST_array(NODE_LIST_array),
    mStartID(startID), mEndID(endID)
{
}
std::mutex mtx;
void CalcWorker::run()
{
  size_t id[8];
  MAPQUADID::iterator itFindQuad;
  for (size_t k = mStartID; k < mEndID; ++k)
  {
    if (!mpActiveGrid[k])
    {
      continue;
    }
    id[0] = (size_t)pNODE_LIST_array->fdata[8 * k] - 1;
    id[6] = (size_t)pNODE_LIST_array->fdata[8 * k + 6] - 1;
    if (mpPointRefCount[id[0]] >= 8 && mpPointRefCount[id[6]] >= 8)
    {
      continue;
    }

    id[2] = (size_t)pNODE_LIST_array->fdata[8 * k + 2] - 1;
    id[4] = (size_t)pNODE_LIST_array->fdata[8 * k + 4] - 1;
    if (mpPointRefCount[id[2]] >= 8 && mpPointRefCount[id[4]] >= 8)
    {
      continue;
    }
    id[1] = (size_t)pNODE_LIST_array->fdata[8 * k + 1] - 1;
    id[7] = (size_t)pNODE_LIST_array->fdata[8 * k + 7] - 1;
    if (mpPointRefCount[id[1]] >= 8 && mpPointRefCount[id[7]] >= 8)
    {
      continue;
    }
    id[3] = (size_t)pNODE_LIST_array->fdata[8 * k + 3] - 1;
    id[5] = (size_t)pNODE_LIST_array->fdata[8 * k + 5] - 1;
    if (mpPointRefCount[id[3]] >= 8 && mpPointRefCount[id[5]] >= 8)
    {
      continue;
    }

    GridQuad grid;
    grid.id      = k;
    grid.quad[0] = new QuadID(k, id[4], id[5], id[6], id[7]);
    grid.quad[1] = new QuadID(k, id[0], id[1], id[2], id[3]);
    grid.quad[2] = new QuadID(k, id[0], id[3], id[7], id[4]);
    grid.quad[3] = new QuadID(k, id[1], id[2], id[6], id[5]);
    grid.quad[4] = new QuadID(k, id[0], id[1], id[5], id[4]);
    grid.quad[5] = new QuadID(k, id[3], id[2], id[6], id[7]);
    mGrids[k]    = grid;

    // 内部角点
    if (mpPointRefCount[id[6]] >= 8)
    {
      grid.quad[0]->isshared = true;
      grid.quad[3]->isshared = true;
      grid.quad[5]->isshared = true;
    }
    if (mpPointRefCount[id[0]] >= 8)
    {
      grid.quad[1]->isshared = true;
      grid.quad[2]->isshared = true;
      grid.quad[4]->isshared = true;
    }
    if (mpPointRefCount[id[2]] >= 8)
    {
      grid.quad[1]->isshared = true;
      grid.quad[3]->isshared = true;
      grid.quad[5]->isshared = true;
    }
    if (mpPointRefCount[id[4]] >= 8)
    {
      grid.quad[0]->isshared = true;
      grid.quad[2]->isshared = true;
      grid.quad[4]->isshared = true;
    }

    if (mpPointRefCount[id[1]] >= 8)
    {
      grid.quad[1]->isshared = true;
      grid.quad[3]->isshared = true;
      grid.quad[4]->isshared = true;
    }
    if (mpPointRefCount[id[7]] >= 8)
    {
      grid.quad[0]->isshared = true;
      grid.quad[2]->isshared = true;
      grid.quad[5]->isshared = true;
    }

    if (mpPointRefCount[id[3]] >= 8)
    {
      grid.quad[1]->isshared = true;
      grid.quad[2]->isshared = true;
      grid.quad[5]->isshared = true;
    }
    if (mpPointRefCount[id[5]] >= 8)
    {
      grid.quad[0]->isshared = true;
      grid.quad[3]->isshared = true;
      grid.quad[4]->isshared = true;
    }
  }
}
